#pragma once

#include <string>
#include <map>
#include <set>
#include <hash_map>
#include <wx/treectrl.h>
#include "TagStorage.h"

class wxImageList;
class wxTreeItemId;
class ClassTree : public wxTreeCtrl{
public:
	ClassTree(wxWindow* parent, wxWindowID id = wxID_ANY,
			  const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize);

	bool Create(wxWindow* parent, wxWindowID id = wxID_ANY,
				const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize);

	void rebuild();
	void update();
	void setFilter(const char* filter, const char* memberFilter);

	const Tag* selectedTag() const{ return selectedTag_; }

protected:
	struct ClassInfo{
		ClassInfo() : hasChildren(false) {}
		typedef std::set<wxTreeItemId> Items;
		Items items;
		bool hasChildren;
		typedef std::vector<std::string> ImplementedMethods;
		ImplementedMethods implementedMethods;
	};

	void onSelectionChanged(wxTreeEvent& event);
	void onKeyDown(wxKeyEvent& event);

	void insertTagItem(const Tag* newTag);
	void insertTagItemMember(const Tag* tag);
	void appendTagItem(const Tag* tag);

	bool matchFilter(const Tag& tag);
	bool matchFilterMember(const Tag& tag);
	bool refilter(wxTreeItemId& root);

	const Tag* tagByItem(wxTreeItemId& item);
	wxTreeItemId itemByTag(const Tag* tag, bool eraseFounded = false);
	const Tag* selectedTag_;

	typedef std::map<const Tag*, wxTreeItemId> ItemByTags;
	ItemByTags itemByTags_;

	wxImageList* imageList_;

	std::string filter_;
	std::string filterMember_;

	typedef stdext::hash_map<std::string, ClassInfo> ClassNameToItemMap;
	ClassNameToItemMap classNameToItem_;

	DECLARE_EVENT_TABLE()
};
